home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr27 / gs26.zip / GSLP.PS < prev    next >
Text File  |  1993-04-20  |  14KB  |  486 lines

  1. %    Copyright (C) 1991, 1993 Aladdin Enterprises.  All rights reserved.
  2. %    Distributed by Free Software Foundation, Inc.
  3. %
  4. % This file is part of Ghostscript.
  5. %
  6. % Ghostscript is distributed in the hope that it will be useful, but
  7. % WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. % to anyone for the consequences of using it or for whether it serves any
  9. % particular purpose or works at all, unless he says so in writing.  Refer
  10. % to the Ghostscript General Public License for full details.
  11. %
  12. % Everyone is granted permission to copy, modify and redistribute
  13. % Ghostscript, but only under the conditions described in the Ghostscript
  14. % General Public License.  A copy of this license is supposed to have been
  15. % given to you along with Ghostscript so you can know your rights and
  16. % responsibilities.  It should be in a file named COPYING.  Among other
  17. % things, the copyright notice and this notice must be preserved on all
  18. % copies.
  19.  
  20. % gslp.ps - format and print text
  21.  
  22. % This utility provides functionality approximately equivalent to the Unix
  23. % `enscript' program.  It prints plain text files using a single font.
  24. % It currently handles tabs and formfeeds, but not backspaces.
  25. % It only works with fixed-pitch fonts.
  26. % Standard flags implemented:
  27. %    -12BclqRr -b -f -F -L -p
  28. % Sun flags implemented:
  29. %    -T<n>    set tab width
  30. % Flags ignored:
  31. %    -GghKkmow -# -C -d -J -n -P -S -s -t -v
  32. % Flags added:
  33. %    --detect
  34. %        treats the file as PostScript if it starts with %!
  35. %    --(heading|footing)-(left|center|right) <string>
  36. %        sets the heading/footing fields; use -B first to clear
  37. %    --first-page <n>
  38. %        sets the first page to print
  39. %    --last-page <n>
  40. %        sets the last page to print
  41. %    --spacing <n>
  42. %        for double (n=2), triple (n=3), etc. spacing
  43. % Also, the string %# in a heading or footing is replaced with the page #.
  44. /PageNumberString (%#) def
  45.  
  46. /lpdict 150 dict def
  47. lpdict begin
  48.  
  49. % Define the initial values of the printing parameters.
  50.  
  51. /BodyFont null def        % use default
  52.   /defaultBodyFont
  53.     { /Courier findfont Landscape { 7 } { 10 } ifelse scalefont } def
  54. /Columns 1 def
  55. /DetectFileType false def
  56. /Footers false def
  57. /FootingLeft () def
  58. /FootingCenter () def
  59. /FootingRight () def
  60. /Headers true def
  61. /HeadingLeft () def
  62. /HeadingCenter () def
  63. /HeadingRight (page ) PageNumberString concatstrings def
  64. /HeadingFont null def        % use default
  65.   /defaultHeadingFont
  66.     { /Courier-Bold findfont 10 scalefont } def
  67. /Landscape false def
  68. /MarginBottom 36 def        % 1/2"
  69. /MarginLeft 36 def        % 1/2"
  70. /MarginRight 36 def        % 1/2"
  71. /MarginTop 36 def        % 1/2"
  72. /MaxLines 9999 def        % max lines per page
  73. /Noisy true def            % i.e., not quiet
  74. /OutFile null def        % null = write directly to device
  75. /PageFirst 1 def
  76. /PageLast 99999 def
  77. /Spacing 1 def
  78. /Tab 8 def
  79. /Truncate false def        % wrap long lines, don't truncate
  80.  
  81. % When writing to a file, we want to write out PostScript;
  82. % when writing to the printer, we want to execute it;
  83. % some commands should be executed regardless.
  84. % lpexec provides for all this.
  85.  
  86. /lpexec        % <arg1> ... <argn> </op> <n> <do_always> lpexec -
  87.  { OutFile null eq
  88.     { pop 1 add true
  89.     }
  90.     { /t exch def 1 add /n exch def cvx
  91.       n { n -1 roll dup wosp } repeat
  92.       OutFile (\n) writestring
  93.       n t
  94.     }
  95.    ifelse
  96.     { pop load exec }
  97.     { { pop } repeat }
  98.    ifelse
  99.  } def
  100.  
  101. /lpmoveto
  102.  { /moveto 2 true lpexec
  103.  } def
  104. /lpshow
  105.  { dup length 0 ne { /show 1 false lpexec } { pop } ifelse
  106.  } def
  107. /lpsetmyfont
  108.  { dup load setfont
  109.    OutFile null ne { cvx /setfont 1 false lpexec } { pop } ifelse
  110.  } def
  111.  
  112. % Define some utility procedures.
  113.  
  114. /banner        % ypos left center right
  115.  { /HFont lpsetmyfont
  116.    3 -1 roll bannerstring pop 0 4 index pwidth showline2 pop
  117.    exch bannerstring pwidth exch sub 2 div 3 index pwidth showline2 pop
  118.    bannerstring pwidth exch sub
  119.    3 -1 roll pwidth showline2 pop
  120.  } def
  121.  
  122. /bannerstring    % string -> string width
  123.   { PageNumberString search
  124.      { exch pop pindex 4 string cvs concatstrings exch concatstrings
  125.      }
  126.     if dup stringwidth pop
  127.   } def
  128.  
  129. /beginpage
  130.  { /lindex 0 def
  131.    /skipping pindex PageFirst ge pindex PageLast le and not def
  132.    /save 0 true lpexec /pagesave exch def
  133.    skipping { nulldevice   /OutFile null def } if
  134.    Headers
  135.     { lheight hdescent add
  136.       HeadingLeft HeadingCenter HeadingRight banner
  137.     } if
  138.    /BFont lpsetmyfont
  139.  } def
  140.  
  141. /endpage
  142.  { lindex 0 ne
  143.     { Footers
  144.        { topskip plength sub hdescent add
  145.          FootingLeft FootingCenter FootingRight banner
  146.        } if
  147.       /showpage 0 false lpexec
  148.     } if
  149.    pagesave /restore 0 true lpexec
  150.    /pindex pindex 1 add def
  151.  } def
  152.  
  153. /fontheight    % <font> fontheight <ascent> <height>
  154.  { gsave setfont
  155.    newpath 0 0 moveto
  156.    (|^_j) false charpath
  157.    pathbbox exch pop dup 2 index sub 4 -2 roll pop pop
  158.    grestore exch 1.25 mul exch 1.25 mul
  159.  } def
  160.  
  161. /wosp
  162.  { OutFile ( ) writestring OutFile exch write==only
  163.  } def
  164.  
  165. /outfont        % name font ->
  166.  { OutFile null ne
  167.     { exch wosp
  168.       dup /FontName get wosp OutFile ( findfont) writestring
  169.       /FontMatrix get 0 get 1000 mul round cvi wosp
  170.       OutFile ( scalefont def\n) writestring
  171.     }
  172.     { pop pop
  173.     }
  174.    ifelse
  175.  } def
  176.  
  177. /StringFF (\f) def
  178. /CharFF StringFF 0 get def
  179. /StringTAB (\t) def
  180. /CharTAB StringTAB 0 get def
  181.  
  182. /showline        % line -> leftover_line (handles \f)
  183.  {  { showline1 dup length 0 eq { exit } if
  184.       dup 0 get CharFF ne { exit } if
  185.       endpage beginpage
  186.       skip1
  187.     }
  188.    loop
  189.  } def
  190.  
  191. /showline1        % line -> leftover_line (handles page break)
  192.  { lindex llength eq { endpage beginpage } if
  193.    lindex colines idiv cowidth mul        % x
  194.    lindex colines mod 1 add lheight mul neg fascent sub    % y
  195.    1 index cowidth add
  196.    showline2
  197.    /lindex lindex 1 add def
  198.  } def
  199.  
  200. /showline2    % string x y xlimit -> leftover_string (handles tabs)
  201.  { 2 index exch 5 2 roll lpmoveto    % xinit xlimit string
  202.     { showline3 dup length 0 eq { exit } if
  203.       dup 0 get CharTAB ne { exit } if
  204.       currentpoint exch 4 index sub tabwx div
  205.     0.05 add ceiling tabwx mul 4 index add exch lpmoveto
  206.       skip1
  207.       currentpoint pop 2 index ge { exit } if
  208.     }
  209.    loop exch pop exch pop
  210.  } def
  211.  
  212. /showline3    % xlimit string -> xlimit leftover_string
  213.         % (finds line break / tab / formfeed)
  214.  { currentpoint pop 2 index exch sub
  215.      cwx div 0.1 add cvi 0 max 1 index length min
  216.    1 index 0 3 -1 roll getinterval
  217.     % look for \f or \t
  218.    StringFF search { exch pop exch pop } if
  219.    StringTAB search { exch pop exch pop } if
  220.    dup lpshow
  221.    length dup 2 index length exch sub getinterval
  222.  } def
  223.  
  224. /skip1
  225.  { dup length 1 sub 1 exch getinterval
  226.  } def
  227.  
  228. % The main printing procedure
  229.  
  230. /lp        % file initial_chars ->
  231.  { /lpline exch def
  232.    /lpfile exch def
  233.    /save 0 true lpexec
  234.  
  235. % Initialize the device and fonts.
  236.    /BFont
  237.      BodyFont null eq { defaultBodyFont } { BodyFont } ifelse def
  238.    /BFont BFont outfont
  239.    Headers Footers or
  240.     { /HFont
  241.         HeadingFont null eq { defaultHeadingFont } { HeadingFont } ifelse def
  242.       /HFont HFont outfont
  243.     }
  244.    if
  245.  
  246. % Get the layout parameters.
  247.    clippath
  248.    Landscape { -90 /rotate 1 true lpexec } if
  249.    BFont setfont ( ) stringwidth pop /cwx exch def
  250.      cwx Tab mul /tabwx exch def
  251.    BFont fontheight /fheight exch def /fascent exch def
  252.    Headers Footers or { HFont fontheight } { 0 0 } ifelse
  253.      /hheight exch def /hascent exch def
  254.      /hdescent hheight hascent sub def
  255.    fheight Spacing mul /lheight exch def
  256.    Headers { hheight lheight add } { 0 } ifelse
  257.      /topskip exch def
  258.    Footers { hheight lheight add } { 0 } ifelse
  259.      /botskip exch def
  260.    /pskip topskip botskip add def
  261.     % Translate the page so that (0,0) corresponds to
  262.     % the top of the topmost body line.
  263.    pathbbox
  264.      2 index sub MarginBottom MarginTop add sub /plength exch def
  265.      2 index sub MarginLeft MarginRight add sub /pwidth exch def
  266.      pwidth Columns div /cowidth exch def
  267.      exch MarginLeft add
  268.      exch MarginBottom add plength add topskip sub
  269.      /translate 2 true lpexec
  270.    plength pskip sub lheight div cvi MaxLines min
  271.      dup /colines exch def
  272.      Columns mul /llength exch def
  273.    OutFile null ne { nulldevice } if
  274.  
  275. % Print layout
  276.    Noisy
  277.     { (Page height = ) print llength =only
  278.       (.\n) print flush
  279.     } if
  280.  
  281. % Disable stack recording so we can use stopped with readline.
  282.    $error /recordstacks false put
  283.  
  284. % Initialize for the first page.
  285.    /lbuf 1000 string def
  286.    /pindex 1 def
  287.    beginpage
  288.  
  289. % Iterate through the file.
  290.    lpline
  291.     { dup length /pos exch def
  292.       lbuf exch 0 exch putinterval
  293.        { lpfile lbuf pos lbuf length pos sub getinterval readline } stopped
  294.        {    % Filled the line before a CR or EOF.
  295.          exch pop showline
  296.        }
  297.        {    % Reached CR and/or EOF first.
  298.          exch length pos add lbuf exch 0 exch getinterval
  299.      1 index { showline } if        % omit final empty line
  300.       { dup length 0 eq Truncate or { pop () exit } if
  301.         showline
  302.       }
  303.      loop
  304.      exch not { exit } if
  305.        }
  306.       ifelse
  307.     } loop
  308.    pop
  309.  
  310. % Wrap up.
  311.    endpage
  312.    /restore 0 true lpexec
  313.  
  314.  } def
  315.  
  316. end
  317.  
  318. % Usage: <file> lp
  319. %   prints <file> using the current parameter settings.
  320. % Usage: [ <arg1> ... <argn> ] lpcommand
  321. %   interprets args like a command line.
  322.  
  323. /lp { save   lpdict begin () lp end   restore } def
  324.  
  325. lpdict begin
  326.  
  327. /splitfn        % (FontNNN) -> <font>
  328.  { dup /arg exch def length
  329.     { dup 0 le { exit } if
  330.       dup 1 sub arg exch get dup 48 ge exch 59 le and not { exit } if
  331.       1 sub
  332.     } loop
  333.    arg exch 0 exch getinterval dup cvn findfont
  334.    exch arg exch anchorsearch pop pop cvr scalefont
  335.  } def
  336.  
  337. % Parse the command line switches.
  338.  
  339. /doswitch    % argn ... arg1 (-?) restofswitch ->
  340.  { exch dup cvn lpdict exch known
  341.     { cvn load exec }
  342.     { exch pop (Unknown switch: ) print print (\n) print flush }
  343.    ifelse
  344.  } def
  345.  
  346. /more        % argn ... arg1 restofswitch ->
  347.  { dup length 0 ne
  348.     { (- ) dup 1 3 index 0 get put
  349.       exch dup length 1 sub 1 exch getinterval
  350.       doswitch
  351.     }
  352.     { pop
  353.     }
  354.    ifelse
  355.  } def
  356.  
  357. /-- { (--) exch concatstrings
  358.       dup cvn lpdict exch known
  359.        { cvn load exec }
  360.        { (Unknown switch: ) print print (\n) print flush }
  361.       ifelse
  362.     } def
  363. /--columns { cvi 1 max /Columns exch def } def
  364. /--detect { /DetectFileType true def } def
  365. /--first-page { cvi /PageFirst exch def } def
  366. /--footing-center { /FootingCenter exch def   /Footers true def } def
  367. /--footing-left { /FootingLeft exch def   /Footers true def } def
  368. /--footing-right { /FootingRight exch def   /Footers true def} def
  369. /--heading-center { /HeadingCenter exch def   /Headers true def } def
  370. /--heading-left { /HeadingLeft exch def   /Headers true def } def
  371. /--heading-right { /HeadingRight exch def   /Headers true def } def
  372. /--margin-bottom { cvr 72.0 mul /MarginBottom exch def } def
  373. /--margin-left { cvr 72.0 mul /MarginLeft exch def } def
  374. /--margin-right { cvr 72.0 mul /MarginRight exch def } def
  375. /--margin-top { cvr 72.0 mul /MarginTop exch def } def
  376. /--last-page { cvi /PageLast exch def } def
  377. /--spacing { cvr /Spacing exch def } def
  378.  
  379. /-# { pop } def        % ignore
  380. /-+ { -- } def
  381. (-1)cvn { /Columns 1 def   more } def
  382. (-2)cvn { /Columns 2 def   more } def
  383. /-b { /HeadingLeft exch def   /HeadingCenter () def   /HeadingRight PageNumberString def
  384.       /Headers true def
  385.       /break true def
  386.     } def
  387. /-B { /HeadingLeft () def   /HeadingCenter () def   /HeadingRight () def
  388.       /Headers false def
  389.       /FootingLeft () def   /FootingCenter () def   /FootingRight () def
  390.       /Footers false def
  391.       /break true def
  392.       more
  393.     } def
  394. /-C { pop } def        % ignore
  395. /-c { /Truncate true def   more } def
  396. /-d { pop } def        % ignore
  397. /-f { splitfn /BodyFont exch def } def
  398. /-F { splitfn /HeadingFont exch def } def
  399. /-G { more } def    % ignore
  400. /-g { more } def    % ignore
  401. /-h { more } def    % ignore
  402. /-J { pop } def        % ignore
  403. /-K { more } def    % ignore
  404. /-k { more } def    % ignore
  405. /-l { 66 -L -B } def
  406. /-L { cvi /MaxLines exch def } def
  407. /-m { more } def    % ignore
  408. /-n { pop } def        % ignore
  409. /-o { more } def    % ignore
  410. /-p { (w) file /OutFile exch def   OutFile (%!\n) writestring } def
  411. /-P { pop } def        % ignore
  412. /-q { /Noisy false def   more } def
  413. /-r { /Landscape true def   more } def
  414. /-R { /Landscape false def   more } def
  415. /-S { pop } def        % ignore
  416. /-s { pop } def        % ignore
  417. /-T { cvi /Tab exch def } def
  418. /-v { pop } def        % ignore
  419. /-w { more } def    % ignore
  420.  
  421. /lp1        % filename ->
  422.  { break not { dup /HeadingLeft exch def } if
  423.    Noisy
  424.     { (Printing ) print dup print (\n) print flush
  425.     } if
  426.    (r) file
  427.         % If requested, check for a PostScript file.
  428.    DetectFileType
  429.     { dup 2 string readstring pop dup (%!) eq
  430.        {    % Yes, it's a PostScript file.
  431.          pop dup 80 string readline pop pop cvx exec
  432.        }
  433.        { lp
  434.        }
  435.       ifelse
  436.     }
  437.     { () lp
  438.     }
  439.    ifelse
  440.  } bind def
  441.  
  442. /lpcstring 100 string def
  443.  
  444. end
  445.  
  446. /lpcommand        % [arg1 ... argn] -> -
  447.  {    % Push the commands on the stack in reverse order
  448.    mark exch
  449.    dup length 1 sub -1 0 { 1 index exch get exch } for pop
  450.    lpdict begin
  451.    /break false def
  452.     { dup mark eq { pop exit } if
  453.       dup length 2 ge { dup 0 get (-) 0 get eq } { false } ifelse
  454.        { dup 0 2 getinterval
  455.          exch dup length 2 sub 2 exch getinterval
  456.      doswitch
  457.        }
  458.        { dup  /matched false def
  459.           { /matched true def   lp1 } lpcstring filenameforall
  460.      matched { pop } { lp1 } ifelse        % let the error happen
  461.        }
  462.       ifelse
  463.     } loop
  464.    OutFile null ne
  465.     { OutFile (%stdout) (w) file ne { OutFile closefile } if
  466.       /OutFile null def
  467.     } if
  468.    end
  469.  } def
  470.  
  471. [ shellarguments
  472.  { ] dup length 0 ne
  473.     { lpcommand
  474.     }
  475.     { (Usage: gslp [-12BclqRr] [-b<header] [-f<font>] [-F<hfont>]\n) print
  476.       (         [-L<lines>] [-p<outfile>] [-T<tabwidth>] [--columns <n>]\n) print
  477.       (         [--detect] [--first-page <page#>] [--last-page <page#>]\n) print
  478.       (         [--(heading|footing)-(left|right|center) <string>]\n) print
  479.       (         [--margin-(top|bottom|left|right) <inches>]\n) print
  480.       (         [--spacing <n>] file1 ... filen\n) print flush
  481.     }
  482.    ifelse
  483.  }
  484.  { pop }
  485. ifelse
  486.